package cn.sumpu.app.guoguojie.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class CmsUtil {

	private final static Logger logger = LoggerFactory.getLogger(CmsUtil.class);

	// 解压zip文件到指定目录
	public static void unzip(String zipFileName, String destDir) {
		createDir(destDir);// 创建输出目录
		ZipInputStream zipInputStream = null;
		try {
			zipInputStream = new ZipInputStream(
					new FileInputStream(zipFileName));
			ZipEntry zipEntry = null;
			while ((zipEntry = zipInputStream.getNextEntry()) != null) {
				String entryName = zipEntry.getName();
				String entryFullPath = destDir + File.separator + entryName;
				if (logger.isDebugEnabled()) {
					logger.debug("processing '" + entryFullPath + "' ......");
				}
				if (zipEntry.isDirectory()) {
					createDir(entryFullPath);
					if (logger.isDebugEnabled()) {
						logger.debug("create file fold '" + entryFullPath
								+ "' success!");
					}
				} else {
					int in = entryFullPath.lastIndexOf(File.separator);
					createDir(entryFullPath.substring(0, in));
					FileOutputStream entryOutputStream = null;
					try {
						entryOutputStream = new FileOutputStream(entryFullPath);
						byte[] buf = new byte[1024];
						int len;
						while ((len = zipInputStream.read(buf)) != -1) {
							entryOutputStream.write(buf, 0, len);
						}
					} finally {
						if (entryOutputStream != null) {
							entryOutputStream.close();
						}
					}
					if (logger.isDebugEnabled()) {
						logger.debug("create file '" + entryFullPath
								+ "' success!");
					}
				}
			}

		} catch (Exception e) {
			if (logger.isErrorEnabled()) {
				logger.error("unzip static file failed, ", e);
			}
		} finally {
			if (zipInputStream != null) {
				try {
					zipInputStream.closeEntry();
				} catch (IOException e) {
					if (logger.isWarnEnabled()) {
						logger.warn("close zipInputStream failure.", e);
					}
				}
			}

		}

	}

	// 创建目录
	public static void createDir(String targetDirPath) {
		File targetFile = new File(targetDirPath);
		if (!targetFile.exists()) {
			if (!targetFile.mkdirs()) {
				if (logger.isDebugEnabled()) {
					logger.debug("create file fold '" + targetDirPath
							+ "' failed.");
				}
			}
		}
	}

	// 生成文件
	public static void generate(String resourcePath, String template,
			Map<String, String> templateParams, String destfile, String charset) {
		VelocityEngine velocityEngine = new VelocityEngine();
		BufferedWriter bw = null;
		FileOutputStream fos = null;
		try {
			Properties p = new Properties();
			p.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
			p.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
			p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, resourcePath);
			velocityEngine.init(p);

			Template t = velocityEngine.getTemplate(template);
			VelocityContext context = new VelocityContext();
			Set<String> keys = templateParams.keySet();
			for (String key : keys) {
				context.put(key, templateParams.get(key));
			}
			fos = new FileOutputStream(destfile);
			bw = new BufferedWriter(new OutputStreamWriter(fos, charset));
			t.merge(context, bw);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bw.close();
				fos.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	@SuppressWarnings("rawtypes")
	public static String getFullPathRelateClass(String relatedPath, Class cls)
			throws IOException {
		String path = null;
		if (relatedPath == null) {
			throw new NullPointerException();
		}
		String clsPath = getPathFromClass(cls);
		File clsFile = new File(clsPath);
		String tempPath = clsFile.getParent() + File.separator + relatedPath;
		File file = new File(tempPath);
		path = file.getCanonicalPath();
		return path;
	}

	@SuppressWarnings("rawtypes")
	public static String getPathFromClass(Class cls) throws IOException {
		String path = null;
		if (cls == null) {
			throw new NullPointerException();
		}
		URL url = getClassLocationURL(cls);
		if (url != null) {
			path = url.getPath();
			if ("jar".equalsIgnoreCase(url.getProtocol())) {
				try {
					path = new URL(path).getPath();
				} catch (MalformedURLException e) {
				}
				int location = path.indexOf("!/");
				if (location != -1) {
					path = path.substring(0, location);
				}
			}
			File file = new File(path);
			path = file.getCanonicalPath();
		}
		return path;
	}

	@SuppressWarnings("rawtypes")
	public static URL getClassLocationURL(final Class cls) {
		if (cls == null)
			throw new IllegalArgumentException("null input: cls");
		URL result = null;
		final String clsAsResource = cls.getName().replace('.', '/')
				.concat(".class");
		final ProtectionDomain pd = cls.getProtectionDomain();
		// java.lang.Class contract does not specify
		// if 'pd' can ever be null;
		// it is not the case for Sun's implementations,
		// but guard against null
		// just in case:
		if (pd != null) {
			final CodeSource cs = pd.getCodeSource();
			// 'cs' can be null depending on
			// the classloader behavior:
			if (cs != null)
				result = cs.getLocation();

			if (result != null) {
				// Convert a code source location into
				// a full class file location
				// for some common cases:
				if ("file".equals(result.getProtocol())) {
					try {
						if (result.toExternalForm().endsWith(".jar")
								|| result.toExternalForm().endsWith(".zip"))
							result = new URL("jar:"
									.concat(result.toExternalForm())
									.concat("!/").concat(clsAsResource));
						else if (new File(result.getFile()).isDirectory())
							result = new URL(result, clsAsResource);
					} catch (MalformedURLException ignore) {
					}
				}
			}
		}

		if (result == null) {
			// Try to find 'cls' definition as a resource;
			// this is not
			// document．d to be legal, but Sun's
			// implementations seem to
			// allow this:
			final ClassLoader clsLoader = cls.getClassLoader();
			result = clsLoader != null ? clsLoader.getResource(clsAsResource)
					: ClassLoader.getSystemResource(clsAsResource);
		}
		return result;
	}

	// just test
	public static void main(String[] args) {
		try {
			 System.out.println(CmsUtil.getFullPathRelateClass("../../cms",CmsUtil.class));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
